<template>
  <div class="dataFactory-editor">
    <div class="editor-header">
      <span class="title">{{ currentTab.name }}</span>
      <div class="btns">
        <el-button size="mini" @click="run">运行</el-button>
        <el-button size="mini" @click="stopTask">停止</el-button>
        <el-button size="mini" @click="saveTask">保存</el-button>
        <el-button size="mini" type="primary" @click="drawer = true">作业设置</el-button>
      </div>
    </div>
    <div class="editor-content">
      <div class="workflow-cavans">
        <flow
          v-if="showFlow"
          v-model="flowData"
          :nodes="nodeCategory"
          @click="nodeClick"
          @edit-data-factory="editDataFactory"
          @delete-data-factory="deleteDataFactory"
        ></flow>
        <!-- 编辑节点 -->
        <el-tabs 
          type="border-card"
          class="edit-box"
          v-if="flowData.length>0"
          v-model="activeName"
          @tab-click="handleClick"
        >
          <template v-for="(node, index) in flowData" v-if="flowData.length > 0">
            <el-tab-pane :label="`${node.nodeType}-${node.name}`" :name="node.nodeType" :key="index">
              <DataForm
                :ref="node.nodeType"
                :node.sync="node"
                :key="`${currentTab.id}_${node.nodeType}_${node.type}`"
                :project_id="project_id"
                @submit="submitFrom"
              />
            </el-tab-pane>
          </template>
        </el-tabs>
      </div>
    </div>
    <el-drawer
      :visible.sync="drawer"
      :with-header="false"
      append-to-body
      title="作业设置"
      size="40%"
    >
     <task-setting v-if="drawer" :id="currentTab.id"></task-setting>
    </el-drawer>

    <!-- 设置关联 -->
    <el-drawer
      :visible.sync="referenceTaskVisible"
      :before-close="beforeCloseReferenceTask"
      :with-header="false"
      append-to-body
      title="关联任务"
      size="40%"
      @opened="referenceTaskOpen"
    >
      <div class="setting-wrapper">
        <div class="setting-right">
          <el-card>
            <div slot="header" class="clearfix">
              <span style="font-size: 16px">关联节点</span>
              <el-button
                style="float: right; padding: 3px 0"
                type="text"
                @click="referenceTaskVisible = false"
                >关闭</el-button
              >
            </div>
            <el-form label-width="120px">
              <el-form-item label="关联子节点">
                <el-select
                  v-model="referenceTaskids"
                  multiple
                  filterable
                  collapse-tags
                  placeholder="请选择关联子节点"
                  @change="setReferenceNode"
                >
                  <el-option
                    v-for="item in filterNodes"
                    :key="item.stateId"
                    :label="item.name"
                    :value="item.stateId"
                  >
                  </el-option>
                </el-select>
              </el-form-item>
            </el-form>
          </el-card>
        </div>
      </div>
    </el-drawer>
    <!-- 运行 -->
    <el-dialog :visible.sync="excuDateDialog" title="选择计划时间" width="30%">
      <el-form>
        <el-form-item label="计划时间" required>
          <el-date-picker
            v-model="execution_date"
            type="datetime"
            placeholder="选择日期"
            style="width: 100%"
          >
          </el-date-picker>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="excuDateDialog = false">取 消</el-button>
        <el-button type="primary" @click="runTask">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { mapState, mapMutations } from "vuex";
import TaskSetting from "./task-setting";
import DataForm from "../components/data-form";
import { Flow } from "VIEW/components";
import { Layout } from "VIEW/components/flow/util.js";
export default {
  name: "dataFactoryEditor",
  components: {
    TaskSetting,
    Flow,
    DataForm
  },
  data() {
    return {
      showFlow: true,
      excuDateDialog: false,
      backfillDialog: false,
      execution_date: "",
      startTime: "",
      endTime: "",
      referenceTaskids: [],
      referenceTaskVisible: false,
      drawer: false,
      flowData: [],
      nodeCategory: [
        {
          groupName: "输入",
          groupId: "1",
          data: []
        },
        {
          groupId: "2",
          groupName: "转换",
          data: []
        },
        {
          groupId: "3",
          groupName: "输出",
          data: []
        }
      ],
      taskOptions: [],
      currentNode: {},
      filterNodes: [],
      project_id: '',
      activeName: ''
    };
  },
  computed: {
    ...mapState({
      currentTab: ({ data }) => data.currentTab
    })
  },
  watch: {
    ["currentTab.id"]: {
      handler(id) {
        // 直接修改 flowdata 在 tab 切换时候会有连线不显示 bug（应该是 flow 组件内部对 数据变化没有及时响应，通过 v-if 对组件进行重新 render 解决）
        this.showFlow = false;
        let flowData = [];
        if ( this.currentTab.content ) {
          const content = JSON.parse(this.currentTab.content)
          if(content.node && content.node.length > 0){
            const node = JSON.parse(JSON.stringify(content.node));
            flowData = node
          } 
        }
        this.$nextTick(() => {
          this.flowData = flowData;
          this.showFlow = true;
          this.project_id = this.currentTab.project_id
        });
      },
      immediate: true
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initData();
      if(this.flowData.length > 0) {
        this.editDataFactory(this.flowData[0])
      }
    })
  },
  methods: {
    ...mapMutations(["updataTabContent", "setCurrentTab"]),
    setReferenceNode() {
      if (this.referenceTaskids.length > 0) {
        let endNode = this.filterNodes[this.filterNodes.length - 1];
        this.currentNode.branches = this.referenceTaskids.map((node, index) => {
          return {
            nextStateId: node,
            branchId: index + 1
          };
        });
      } else {
        this.currentNode.branches = [];
      }
    },
    // 节点被点击
    nodeClick(data) {
      this.activeName = data.nodeType
      this.currentNode = data;
      if (data.nodeType === "writer") return;
      this.referenceTaskVisible = true;
      
    },
    editDataFactory(data) {
      this.currentNode = data
      this.activeName = data.nodeType
    },
    editOpen() {
      // 编辑参数获取
    },
    beforeCloseEdit() {
      // 表单校验
      this.$refs.dataForm.validate()
    },
    deleteDataFactory(data, index) {
      // 删除
    },
    referenceTaskOpen() {
      this.filterNodes = this.flowData.filter(node => {
        // 输入 -> 转换 -> 输出
        if(this.currentNode.nodeType === 'reader') {
          return node.nodeType == 'filter'
        }
        if(this.currentNode.nodeType === 'filter') {
          return node.nodeType == 'writer'
        }
      });
      this.referenceTaskids = this.currentNode.branches.map(branch => branch.nextStateId) || [];
    },
    beforeCloseReferenceTask(done) {
      this.taskOptions = [];
      this.referenceTaskids = [];
      done();
    },
    initData() {
      this.$http.task.getDatafactoryTypes({ type: this.currentTab.type }).then(res => {
        const {reader_options, writer_options, filter_options} = res
        this.nodeCategory[0].data = reader_options.map((item, index) => {
          return {
            nodeId: index + 1,
            type: item.value,
            name: item.label,
            nodeType: item.nodeType // 输入
          };
        });
        this.nodeCategory[1].data = filter_options.map((item, index) => {
          return {
            nodeId: index + 1,
            type: item.value,
            name: item.label,
            nodeType: item.nodeType // 转换
          };
        });
        this.nodeCategory[2].data = writer_options.map((item, index) => {
          return {
            nodeId: index + 1,
            type: item.value,
            name: item.label,
            nodeType: item.nodeType // 输出
          };
        });
      });
    },
    run() {
      let { content } = this.currentTab;
      if (/{{[d|t]s/.test(content)) {
        this.excuDateDialog = true;
      } else {
        this.runTask();
      }
    },
    runTask() {
      let { execution_date } = this;
      let param = { task_id: this.currentTab.id };
      if (this.excuDateDialog) {
        param.execution_date = +new Date(execution_date);
      } else {
        param.execution_date = null;
      }
      this.$http.task.runTask(param).then(res => {
        this.excuDateDialog = false;
        this.$message({
          type: "success",
          message: "运行成功"
        });

        this.$bus.$emit("refresh-task-history");
      });
    },
    stopTask() {
      this.$http.task
        .stopTask({
          dag_id: this.currentTab.dag_id,
          task_id: this.currentTab.task_id,
          execution_date: this.currentTab.execution_date
        })
        .then(res => {
          this.$bus.$emit("refresh-task-history");
        });
    },
    submitFrom(data) {
      this.param = {
        ...this.param,
        ...data
      }
    },
    async validate() {
      // 判断有输入、转换、输出3个节点
      if(this.flowData.length < 3) {
        let str = ''
        let arr = this.flowData.map(item => {
          return item.nodeType
        })
        if(arr.indexOf('reader') < 0) {
          str = '输入'
        }
        if(arr.indexOf('filter') < 0) {
          str = str ? str + '、' + '转换' : '转换'
        }
        if(arr.indexOf('writer') < 0) {
          str =  str ? str + '、' + '输出' : '输出'
        }
        this.$message.warning(`该任务缺少 ${str} 节点`)
        return false
      } else {
        // 表单校验
        const writerValid = await this.$refs.writer[0].validate()
        const filterValid = await this.$refs.filter[0].validate()
        const readerValid = await this.$refs.reader[0].validate()
        return writerValid && readerValid && filterValid
      }
    },
    async saveTask() {
      const valid = await this.validate()
      if(valid) {
        let { id, content, param } = this.currentTab;
        content = {
          // ...content,
          node: this.flowData,
        }
        param = {
          envId: '',
          sparkArgs: {},
          isStreaming: true,
          isMetricsMonitor: false,
          ...param,
          ...this.param
        }
        this.$http.task.updateTask({ id, content, param}).then(res => {
          this.$message({
            type: "success",
            message: "保存成功"
          });
          // 同步全局变量
          let curContent = {
            ...this.currentTab,
            content,
            param: this.param
          };
          this.setCurrentTab(curContent)
        });
      }
    },
  }
};
</script>
<style lang="scss">
.dataFactory-editor {
  height: 50%;
  flex: 1;
  position: relative;
  .editor-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #e4e7ed;
    padding: 8px 8px;
  }
  .editor-content {
    height: calc(100% - 40px);
    overflow: hidden;
    position: relative;
    .workflow-cavans {
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
    }
    // .CodeMirror {
    //   height: 100%;
    // }
  }
}
.setting-wrapper {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  overflow: hidden;
  display: flex;
  .setting-right {
    flex: 1;
    & > .el-card {
      border: none;
      box-shadow: none;
    }
    .el-card__header {
      padding: 16px 20px;
    }
  }
  .el-menu {
    height: 100%;
  }
}
.referen-children {
  display: flex;
  justify-content: center;
}
.edit-box{
  position: absolute;
  right: 12px;
  top: 20px;
  height: 86%;
  width: 400px;
  // box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  // padding: 10px;
  background: #fff;
  overflow: hidden;
}
.el-tabs__content{
  overflow-y: scroll;
  height: 100%;
  box-sizing: border-box;
}
</style>
